#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdio.h>

int initDivSock(int port);

/**
 *  This is a vanila program used for baselining performance.
 *  Grabs packets from divsocket and passes it right on. 
 *  This gives us the best-case scenario for using divert socket and allows us to get cost of using divertsocket, and extra cost that our fw (and its rule matching logic) adds
 *
 */
int main(int argc, char *argv[]){

	int divport = 0;
	if(argc != 2){
		printf("usage: testperf [div port]\n");
		return 1;
	}
	divport = atoi(argv[1]);	

	int divsock = initDivSock(divport);

	if(divsock == -1){
		printf("Unable to create divert socket\n");
		return 1;
	}
	const int buflen = 2048;
	int pktlen = 0;
	unsigned char buf[buflen];
	struct sockaddr_in insockaddr;
	unsigned int addrsize = sizeof(struct sockaddr);
	while(1){
		pktlen = recvfrom(divsock, buf, buflen, 0, (struct sockaddr *) &insockaddr, &addrsize);
				sendto(divsock, buf, pktlen, 0, (struct sockaddr *) &insockaddr, addrsize);
	}

	//do clean up, closing log file, divsock
}

/*
 * initializes divertsocket and returns the socket file descriptor
 * returns -1 if unable to initialize
 */
int initDivSock(int port){
	struct sockaddr_in addr;
	int sockfd;

	sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT);
	if(sockfd == -1){
		return -1;
	}

	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(port);

	if (bind(sockfd, (struct sockaddr*) &addr, sizeof addr) == -1){
		return -1;
	}

	return sockfd;
}
